package com.textmanager.ui;

import com.textmanager.db.DirectoryDAO;
import com.textmanager.db.TextFileDAO;
import com.textmanager.model.Directory;
import com.textmanager.model.TextFile;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.sql.SQLException;
import java.util.List;

public class DirectoryTreePanel extends JPanel {

    private JTree directoryTree;
    private DefaultTreeModel treeModel;
    private TextEditorPanel textEditorPanel;

    private JTextField searchField;
    private DefaultMutableTreeNode originalRoot;
    private boolean firstNoteLoaded = false; // Flag to ensure it only runs once

    public DirectoryTreePanel() {
        setBackground(new Color(240, 240, 240));

        setLayout(new BorderLayout());
        initTree();
        
        // 创建搜索框
        searchField = new JTextField(20);
        searchField.getDocument().addDocumentListener(new javax.swing.event.DocumentListener() {
            public void insertUpdate(javax.swing.event.DocumentEvent e) { filterTree(); }
            public void removeUpdate(javax.swing.event.DocumentEvent e) { filterTree(); }
            public void changedUpdate(javax.swing.event.DocumentEvent e) { filterTree(); }
        });
        
        // 创建搜索面板
        JPanel searchPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        searchPanel.add(new JLabel("搜一下："));
        searchPanel.add(searchField);
        
        add(searchPanel, BorderLayout.NORTH);
        add(new JScrollPane(directoryTree), BorderLayout.CENTER);
        // Removed toolbar, functionality moved to context menu
        // add(createToolbar(), BorderLayout.SOUTH);
    }

    public void setTextEditorPanel(TextEditorPanel textEditorPanel) {
        this.textEditorPanel = textEditorPanel;
    }

    private void initTree() {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode(new Directory(1, "根目录", null));
        originalRoot = root;
        treeModel = new DefaultTreeModel(root);
        directoryTree = new JTree(treeModel);
        directoryTree.setCellRenderer(new DefaultTreeCellRenderer() {
            @Override
            public Component getTreeCellRendererComponent(JTree tree, Object value,
                    boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
                super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
                Object userObject = node.getUserObject();
                if (userObject instanceof Directory) {
                    setIcon(expanded ? getOpenIcon() : getClosedIcon());
                } else if (userObject instanceof TextFile) {
                    setIcon(getLeafIcon());
                }
                return this;
            }
        });
        loadDirectoryStructure(root);
        expandAllNodes(directoryTree, 0, directoryTree.getRowCount());

        directoryTree.addTreeSelectionListener(e -> {
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) directoryTree.getLastSelectedPathComponent();
            if (textEditorPanel != null) {
                if (node != null && node.getUserObject() instanceof TextFile) {
                    TextFile file = (TextFile) node.getUserObject();
                    textEditorPanel.loadFile(file);
                    textEditorPanel.setEditorEnabled(true);
                } else if (node != null && node.getUserObject() instanceof Directory) {
                    textEditorPanel.clearEditor();
                    textEditorPanel.setEditorEnabled(false);
                } else {
                    textEditorPanel.clearEditor(); // Clear editor if nothing or root is selected
                    textEditorPanel.setEditorEnabled(false);
                }
            }
        });

        directoryTree.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent e) {
                if (SwingUtilities.isRightMouseButton(e)) {
                    TreePath path = directoryTree.getPathForLocation(e.getX(), e.getY());
                    if (path != null) {
                        directoryTree.setSelectionPath(path);
                        DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) path.getLastPathComponent();
                        showPopupMenu(e.getX(), e.getY(), selectedNode);
                    }
                }
            }
        });
    }

    private void loadDirectoryStructure(DefaultMutableTreeNode parentNode) {
        try {
            Directory parentDir = (Directory) parentNode.getUserObject();
            // Load subdirectories
            List<Directory> directories = DirectoryDAO.getChildDirectories(parentDir.getId());
            for (Directory dir : directories) {
                DefaultMutableTreeNode dirNode = new DefaultMutableTreeNode(dir);
                treeModel.insertNodeInto(dirNode, parentNode, parentNode.getChildCount());
                loadDirectoryStructure(dirNode);
            }

            // Load files
            List<TextFile> files = TextFileDAO.getFilesInDirectory(parentDir.getId());
            for (TextFile file : files) {
                DefaultMutableTreeNode fileNode = new DefaultMutableTreeNode(file);
                treeModel.insertNodeInto(fileNode, parentNode, parentNode.getChildCount());
            }
        } catch (SQLException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(this, "加载目录结构失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    // Removed createToolbar method as toolbar is no longer used.

    private void showPopupMenu(int x, int y, DefaultMutableTreeNode selectedNode) {
        JPopupMenu popupMenu = new JPopupMenu();
        Object userObject = selectedNode.getUserObject();

        if (userObject instanceof Directory) {
            Directory dir = (Directory) userObject;

            JMenuItem addDirItem = new JMenuItem("添加目录");
            addDirItem.addActionListener(e -> addDirectory());
            popupMenu.add(addDirItem);

            JMenuItem addFileItem = new JMenuItem("添加笔记");
            addFileItem.addActionListener(e -> addFile());
            popupMenu.add(addFileItem);

            if (dir.getId() != 1) { // Not the root directory
                JMenuItem editDirItem = new JMenuItem("修改名称");
                editDirItem.addActionListener(e -> editNode());
                popupMenu.add(editDirItem);

                JMenuItem deleteDirItem = new JMenuItem("删除目录");
                deleteDirItem.addActionListener(e -> deleteNode());
                // Optionally, disable if directory is not empty
                try {
                    if (!DirectoryDAO.getChildDirectories(dir.getId()).isEmpty() || !TextFileDAO.getFilesInDirectory(dir.getId()).isEmpty()) {
                        deleteDirItem.setEnabled(false);
                    }
                } catch (SQLException ex) {
                    // Handle exception, maybe log or disable
                    deleteDirItem.setEnabled(false);
                }
                popupMenu.add(deleteDirItem);
            }
        } else if (userObject instanceof TextFile) {
            JMenuItem editFileItem = new JMenuItem("修改名称");
            editFileItem.addActionListener(e -> editNode());
            popupMenu.add(editFileItem);

            JMenuItem deleteFileItem = new JMenuItem("删除笔记");
            deleteFileItem.addActionListener(e -> deleteNode());
            popupMenu.add(deleteFileItem);
        }

        if (popupMenu.getComponentCount() > 0) {
            popupMenu.show(directoryTree, x, y);
        }
    }

    private void addDirectory() {
        DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) directoryTree.getLastSelectedPathComponent();
        if (selectedNode == null || !(selectedNode.getUserObject() instanceof Directory)) {
            JOptionPane.showMessageDialog(this, "请先选择一个目录", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }

        String name = JOptionPane.showInputDialog(this, "请输入目录名称:", "新建目录", JOptionPane.PLAIN_MESSAGE);
        if (name != null && !name.trim().isEmpty()) {
            try {
                Directory parentDir = (Directory) selectedNode.getUserObject();
                Directory newDir = DirectoryDAO.createDirectory(name.trim(), parentDir.getId());
                DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(newDir);
                treeModel.insertNodeInto(newNode, selectedNode, selectedNode.getChildCount());
                // Expand the parent node to make the new node visible
                TreePath pathToNode = new TreePath(newNode.getPath());
                directoryTree.expandPath(pathToNode.getParentPath());
                directoryTree.scrollPathToVisible(pathToNode);
            } catch (SQLException e) {
                e.printStackTrace();
                JOptionPane.showMessageDialog(this, "创建目录失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    private void addFile() {
        DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) directoryTree.getLastSelectedPathComponent();
        if (selectedNode == null || !(selectedNode.getUserObject() instanceof Directory)) {
            JOptionPane.showMessageDialog(this, "请先选择一个目录", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }

        String name = JOptionPane.showInputDialog(this, "请输入文件名称:", "新建文件", JOptionPane.PLAIN_MESSAGE);
        if (name != null && !name.trim().isEmpty()) {
            try {
                Directory parentDir = (Directory) selectedNode.getUserObject();
                TextFile newFile = TextFileDAO.createFile(name.trim(), "", parentDir.getId());
                DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(newFile);
                treeModel.insertNodeInto(newNode, selectedNode, selectedNode.getChildCount());
                // Expand the parent node to make the new node visible
                TreePath pathToNode = new TreePath(newNode.getPath());
                directoryTree.expandPath(pathToNode.getParentPath());
                directoryTree.scrollPathToVisible(pathToNode);
            } catch (SQLException e) {
                e.printStackTrace();
                JOptionPane.showMessageDialog(this, "创建文件失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    private void editNode() {
        DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) directoryTree.getLastSelectedPathComponent();
        if (selectedNode == null) {
            JOptionPane.showMessageDialog(this, "请先选择一个节点", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }

        Object userObject = selectedNode.getUserObject();
        String newName = JOptionPane.showInputDialog(this, "请输入新名称:", "重命名", JOptionPane.PLAIN_MESSAGE);
        
        if (newName != null && !newName.trim().isEmpty()) {
            try {
                if (userObject instanceof Directory) {
                    Directory dir = (Directory) userObject;
                    dir.setName(newName.trim());
                    DirectoryDAO.updateDirectory(dir);
                } else if (userObject instanceof TextFile) {
                    TextFile file = (TextFile) userObject;
                    file.setName(newName.trim());
                    TextFileDAO.updateFile(file);
                }
                treeModel.nodeChanged(selectedNode);
            } catch (SQLException e) {
                e.printStackTrace();
                JOptionPane.showMessageDialog(this, "重命名失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    private void deleteNode() {
        DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) directoryTree.getLastSelectedPathComponent();
        if (selectedNode == null) {
            JOptionPane.showMessageDialog(this, "请先选择一个节点", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }

        Object userObject = selectedNode.getUserObject();
        int result = JOptionPane.showConfirmDialog(this, "确定要删除吗？", "确认删除", JOptionPane.YES_NO_OPTION);
        
        if (result == JOptionPane.YES_OPTION) {
            try {
                if (userObject instanceof Directory) {
                    Directory dir = (Directory) userObject;
                    // Check if the directory is empty
                    List<Directory> childDirs = DirectoryDAO.getChildDirectories(dir.getId());
                    List<TextFile> filesInDir = TextFileDAO.getFilesInDirectory(dir.getId());
                    if (!childDirs.isEmpty() || !filesInDir.isEmpty()) {
                        JOptionPane.showMessageDialog(this, "目录不为空，无法删除。请先删除目录下的所有文件和子目录。", "错误", JOptionPane.ERROR_MESSAGE);
                        return;
                    }
                    DirectoryDAO.deleteDirectory(dir.getId());
                } else if (userObject instanceof TextFile) {
                    TextFile file = (TextFile) userObject;
                    TextFileDAO.deleteFile(file.getId());
                }
                treeModel.removeNodeFromParent(selectedNode);
            } catch (SQLException e) {
                e.printStackTrace();
                JOptionPane.showMessageDialog(this, "删除失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    public void refreshTree() {
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) treeModel.getRoot();
        root.removeAllChildren();
        loadDirectoryStructure(root);
        treeModel.reload();
        expandAllNodes(directoryTree, 0, directoryTree.getRowCount());
        originalRoot = root;
    }

    private void filterTree() {
        String searchText = searchField.getText().toLowerCase().trim();
        if (searchText.isEmpty()) {
            treeModel.setRoot(originalRoot);
        } else {
            DefaultMutableTreeNode filteredRoot = filterNode(originalRoot, searchText);
            if (filteredRoot != null) {
                treeModel.setRoot(filteredRoot);
            } else {
                treeModel.setRoot(new DefaultMutableTreeNode("无搜索结果"));
            }
        }
        expandAllNodes(directoryTree, 0, directoryTree.getRowCount());
        // loadFirstNoteOnStartup(); // Moved to MainFrame after textEditorPanel is set
    }

    public void loadFirstNoteOnStartup() {
        if (firstNoteLoaded || textEditorPanel == null) {
            return;
        }
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) treeModel.getRoot();
        DefaultMutableTreeNode firstFileNode = findFirstFileNode(root);
        if (firstFileNode != null) {
            TreePath path = new TreePath(firstFileNode.getPath());
            directoryTree.setSelectionPath(path);
            directoryTree.scrollPathToVisible(path);
            TextFile file = (TextFile) firstFileNode.getUserObject();
            textEditorPanel.loadFile(file);
            textEditorPanel.setEditorEnabled(true);
            firstNoteLoaded = true;
        } else {
            // No file found, clear editor and disable
            textEditorPanel.clearEditor();
            textEditorPanel.setEditorEnabled(false);
        }
    }

    private DefaultMutableTreeNode findFirstFileNode(DefaultMutableTreeNode node) {
        if (node.getUserObject() instanceof TextFile) {
            return node;
        }
        for (int i = 0; i < node.getChildCount(); i++) {
            DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) node.getChildAt(i);
            DefaultMutableTreeNode fileNode = findFirstFileNode(childNode);
            if (fileNode != null) {
                return fileNode;
            }
        }
        return null;
    }

    private void expandAllNodes(JTree tree, int startingIndex, int rowCount){
        for(int i=startingIndex; i<rowCount; ++i){
            tree.expandRow(i);
        }

        if(tree.getRowCount()!=rowCount){
            expandAllNodes(tree, rowCount, tree.getRowCount());
        }
    }
    private DefaultMutableTreeNode filterNode(DefaultMutableTreeNode node, String searchText) {
        if (node == null) {
            return null;
        }

        // Check if the current node's name or content matches
        boolean matches = false;
        Object userObject = node.getUserObject();
        String nodeName = "";
        boolean contentMatches = false;

        try {
            if (userObject instanceof Directory) {
                Directory dir = (Directory) userObject;
                nodeName = dir.getName().toLowerCase();
                // Check if any file in this directory or subdirectories contains the search text
                contentMatches = directoryContainsMatchingFile(dir, searchText);
            } else if (userObject instanceof TextFile) {
                TextFile file = (TextFile) userObject;
                nodeName = file.getName().toLowerCase();
                contentMatches = file.getContent().toLowerCase().contains(searchText);
            }

            if (nodeName.contains(searchText) || contentMatches) {
                matches = true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        // 创建新节点
        DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(userObject);

        // 递归处理子节点
        java.util.Enumeration<?> children = node.children();
        while (children.hasMoreElements()) {
            DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) children.nextElement();
            DefaultMutableTreeNode filteredChild = filterNode(childNode, searchText);
            if (filteredChild != null) {
                newNode.add(filteredChild);
            }
        }

        // 如果当前节点匹配或有匹配的子节点，则返回该节点
        if (matches || newNode.getChildCount() > 0) {
            return newNode;
        }
        return null;
    }

    private boolean directoryContainsMatchingFile(Directory directory, String searchText) throws SQLException {
        // Check if any file in this directory (or subdirectories, handled by TextFileDAO.searchFilesByContent if it were designed for recursive search)
        // For now, searchFilesByContent searches all files. We need to filter by directory.
        // Let's refine this to check files within the current directory and its subdirectories.

        // Check files directly in this directory
        List<TextFile> filesInCurrentDir = TextFileDAO.getFilesInDirectory(directory.getId());
        for (TextFile file : filesInCurrentDir) {
            if (file.getContent().toLowerCase().contains(searchText)) {
                return true;
            }
        }

        // Recursively check subdirectories
        List<Directory> subDirs = DirectoryDAO.getChildDirectories(directory.getId());
        for (Directory subDir : subDirs) {
            if (directoryContainsMatchingFile(subDir, searchText)) { // Recursive call
                return true;
            }
        }
        return false;
    }
}